/*
 ============================================================================
 Name        : connect.c
 Author      : bird
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <event2/dns.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/util.h>
#include <event2/event.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
char buf[5120];
void readcb(struct bufferevent *bev, void *ptr)
{
    struct evbuffer *input = bufferevent_get_input(bev);
    struct evbuffer *output = bufferevent_get_output(bev);
    printf(" r <- \n");
    evbuffer_add_buffer(output, input);
}

void writecb(struct bufferevent *bev, void *ptr)
{
	  assert( !bufferevent_write(bev, buf,  5120));
	  sleep(1);
}
/*
 *
 */
void eventcb(struct bufferevent *bev, short events, void *ptr)
{
    if (events & BEV_EVENT_CONNECTED) {

    	 printf("Connect okay.\n");
         bufferevent_write(bev, buf,  5120);

    } else if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF))
    {
         struct event_base *base = ptr;
         if (events & BEV_EVENT_ERROR) {
                 int err = bufferevent_socket_get_dns_error(bev);
                 if (err)
                         printf("DNS error: %s\n", evutil_gai_strerror(err));
         }
         printf("Closing\n");
         bufferevent_free(bev);
         event_base_loopexit(base, NULL);
    }
}




int main(int argc, char **argv)
{
    struct event_base *base;
//    struct evdns_base *dns_base;
    struct bufferevent *bev;
	memset(buf+1,244,5118);
	buf[0]='0';
	buf[5119]='0';
	struct sockaddr_in sin;
	memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1"); /* 127.0.0.1 */
    sin.sin_port = htons(5000); /* Port 8080 */
    base = event_base_new();

//    dns_base = evdns_base_new(base, 1);

    bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);

    bufferevent_setcb(bev, readcb, writecb, eventcb, base);
     bufferevent_enable(bev, EV_READ|EV_WRITE);

	if (bufferevent_socket_connect(bev,(struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
        /* Error starting connection */
        bufferevent_free(bev);
        return -1;
    }

    printf(" connect ok ");

    event_base_dispatch(base);
    return 0;
}




//void
//read_callback_uppercase(struct bufferevent *bev, void *ctx)
//{
//        /* This callback removes the data from bev's input buffer 128
//           bytes at a time, uppercases it, and starts sending it
//           back.

//           (Watch out!  In practice, you shouldn't use toupper to implement
//           a network protocol, unless you know for a fact that the current
//           locale is the one you want to be using.)
//         */

//        char tmp[128];
//        size_t n;
//        int i;
//        while (1) {
//                n = bufferevent_read(bev, tmp, sizeof(tmp));
//                if (n <= 0)
//                        break; /* No more data. */
//                for (i=0; i<n; ++i)
//                        tmp[i] = toupper(tmp[i]);
//                bufferevent_write(bev, tmp, n);
//        }
//}

//struct proxy_info {
//        struct bufferevent *other_bev;
//};
//void
//read_callback_proxy(struct bufferevent *bev, void *ctx)
//{
//        /* You might use a function like this if you're implementing
//           a simple proxy: it will take data from one connection (on
//           bev), and write it to another, copying as little as
//           possible. */
//        struct proxy_info *inf = ctx;

//        bufferevent_read_buffer(bev,
//            bufferevent_get_output(inf->other_bev));
//}

//struct count {
//        unsigned long last_fib[2];
//};

//void
//write_callback_fibonacci(struct bufferevent *bev, void *ctx)
//{
//        /* Here's a callback that adds some Fibonacci numbers to the
//           output buffer of bev.  It stops once we have added 1k of
//           data; once this data is drained, we'll add more. */
//        struct count *c = ctx;

//        struct evbuffer *tmp = evbuffer_new();
//        while (evbuffer_get_length(tmp) < 1024) {
//                 unsigned long next = c->last_fib[0] + c->last_fib[1];
//                 c->last_fib[0] = c->last_fib[1];
//                 c->last_fib[1] = next;

//                 evbuffer_add_printf(tmp, "%lu", next);
//        }

//        /* Now we add the whole contents of tmp to bev. */
//        bufferevent_write_buffer(bev, tmp);

//        /* We don't need tmp any longer. */
//        evbuffer_free(tmp);
//}
